package com.cxd.app.service;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cxd.app.entity.base.AuthInfoBase;
import com.cxd.base.common.constants.CommonConstants;
import com.cxd.base.common.exception.AuthInfoAlreadyActivedException;
import com.cxd.base.common.exception.AuthInfoOutOfDateException;
import com.cxd.base.common.exception.CxdException;
import com.cxd.base.common.exception.NoMatchingObjectsException;
import com.cxd.base.util.BeanTools;
import com.cxd.base.util.IdGenerator;
import com.sun.tools.internal.ws.wscompile.AuthInfo;

/**
 * <一句话功能简述> <功能详细描述>
 * @author wtj
 * @date 2015年12月2日 下午3:18:52
 * @company CXD
 * @version [Copyright (c) 2015 V001]
 */
@Service("authService")
public class AuthService {
	@Resource
	public BeanTools bt;
	
	
	private static final Logger log = Logger.getLogger(AuthService.class);
	
	/**
	 * 生成验证码
	 * @author wtj
	 * @date 2015年12月8日下午7:55:47
	 * @param source
	 * @param target
	 * @param deadline
	 * @param authType
	 * @return
	 */
	@Transactional
	public AuthInfoBase createAuthInfo(String source, String target, Date deadline,
			String authType) {
		AuthInfoBase ai = new AuthInfoBase();
		ai.setId(IdGenerator.randomUUID());
		ai.setAuthTarget(target);
		ai.setAuthSource(source);
		ai.setAuthType(authType);
		ai.setAuthCode(RandomStringUtils.random(6, false, true));
		ai.setStatus(CommonConstants.AuthInfoStatus.INACTIVE);
		ai.setDeadline(deadline);
		ai.setGenerationTime(new Date());
		bt.update("DELETE FROM AUTH_INFO WHERE AUTH_TARGET='"+target.trim()+"' AND AUTH_TYPE='"+authType.trim()+"'");
		bt.add(ai);
		return ai;
	}
	
	/**
	 * 验证认证码
	 * @param source 可以使userid，也可以自己约定
	 * @param target 邮箱或者手机号
	 * @param authCode 认证码
	 * @param authType 认证码类型
	 */
	public void verifyAuthInfo(String source, String target, String authCode,
			String authType) throws NoMatchingObjectsException,
			AuthInfoOutOfDateException, AuthInfoAlreadyActivedException,InstantiationException,IllegalAccessException {
		if (log.isDebugEnabled()) {
			log.debug("source:" + source + " target:" + target + " authCode:"
					+ authCode + " authType:" + authType);
		}
		AuthInfoBase ai = this.get(source, target, authType);
		if (ai == null || !StringUtils.equals(ai.getAuthCode(), authCode)) {
//			// 没找到或认证码不正确，抛异常，目前已有异常不合适
//			throw new NoMatchingObjectsException(AuthInfo.class, "source:"
//					+ source + " target:" + target + " authCode:" + authCode
//					+ " authType:" + authType);
			throw new CxdException("验证码错误");
		}
		if (!StringUtils.equals(ai.getStatus(),
				CommonConstants.AuthInfoStatus.INACTIVE)) {
			// FIXME:不是未激活状态，抛异常
			throw new AuthInfoAlreadyActivedException("source:"
					+ source + " target:" + target + " authCode:" + authCode
					+ " authType:" + authType);
		}
		if (ai.getDeadline() != null && ai.getDeadline().before(new Date())) {
			// FIXME:已经过期，抛异常
			throw new AuthInfoOutOfDateException("source:" + source
					+ " target:" + target + " authCode:" + authCode
					+ " authType:" + authType);
		}
	}
	
	/**
	 * 存储一个来源，查询时候，来源、目标、类型，三个作为联合主键。
	 * @param source 可以使userid，也可以自己约定
	 * @param target 邮箱或者手机号
	 * @param authType 认证码类型
	 * @return
	 */
	public AuthInfoBase get(String source, String target, String authType)throws InstantiationException,IllegalAccessException {
		String[] columns = {"AUTH_TARGET","AUTH_TYPE"}; 
		String[] values = {null,null}; 
		if(StringUtils.isNotBlank(target)){
			values[0] = target;
		}
		if(StringUtils.isNotBlank(authType)){
			values[1] = authType;
		}
		List<AuthInfoBase> ais = bt.queryListBean("AUTH_INFO", columns, values, AuthInfoBase.class," ORDER by generation_time DESC ");
		if (ais==null || ais.size() == 0) {
			return null;
		}
		return ais.get(0);
	}
	
}
